﻿using Microsoft.Extensions.Caching.Memory;
using Nancy.Json;
using NewLife.Caching;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

using NewLife.Redis.Core;
using UtilsBase;
using NewLife.Serialization.Json;

namespace UtilsCache
{ /// <summary>
  /// 2023年以前都不支持分布式锁
  /// </summary>
    public class UtilRedisNewLife
    {
        private static NewLifeRedis redis;
        static UtilRedisNewLife()
        {
            if (redis == null)
            {

                string connStr = "" + UtilAppsettingCache.getSetting("redis:host") + "; password=" + UtilAppsettingCache.getSetting("redis:password") + ";db="+ UtilAppsettingCache.getSetting("redis:db");
                redis = new NewLifeRedis(connStr);
            }

            //https://blog.csdn.net/hu531035580/article/details/129809394

        }
        public static void set(string key, object value)
        {
            //被动过期 （绝对时间过期）
            //var cacheopetions = new MemoryCacheEntryOptions()
            //{
            //    //设置过期时间（5秒）
            //    AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(exprireMins)
            //};
            ////设置过期回调函数
            //cacheopetions.RegisterPostEvictionCallback((key, value, reason, obj) =>
            //{
            //    Console.WriteLine(reason);
            //});

            redis.Set(key, value);
        }

        public static void set(string key, object value, int exprireMins)
        {

            //被动过期 （绝对时间过期）
            //var cacheopetions = new MemoryCacheEntryOptions()
            //{
            //    //设置过期时间（5秒）
            //    AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(exprireMins)
            //};
            ////设置过期回调函数
            //cacheopetions.RegisterPostEvictionCallback((key, value, reason, obj) =>
            //{
            //    Console.WriteLine(reason);
            //});
            redis.Set(key, value, TimeSpan.FromMinutes(exprireMins));
        }
        //public static void set<T>(string key, T value)
        //{
        //    redis.Set<T>(key, value);
        //}
        public static bool set<T>(string key, T value, int exprireMins = 1)
        {
            //实体类需要有{ get; set; }，否则设置不了值
            //return redis.Set<string>(key, JsonConvert.SerializeObject(value), TimeSpan.FromMinutes(exprireMins));
            return redis.Set(key, value, TimeSpan.FromMinutes(exprireMins));
        }

        public static T get<T>(string key)
        {
            // try
            // {
            //  return JsonConvert.DeserializeObject<T>(redis.Get<string>(key));
            return redis.Get<T>(key);
            // }
            //catch(Exception ex)
            // {
            //     remove(key);
            //    return default(T);
            // }
        }

        public static bool set(string key, string value, int exprireMins = 1)
        {
            return redis.Set(key, value, TimeSpan.FromMinutes(exprireMins));
        }

        public static void remove(string key)
        {
            redis.Remove(key);
        }

        //public static void waitUnLock(string key)
        //{
        //    string lockobj = redis.Get<string>(key);
        //    while (lockobj != null)
        //    {
        //        lockobj = redis.Get<string>(key);
        //        Thread.Sleep(50);
        //    }
        //}
        //public static void setLock(string key)
        //{
        //    // UtilsCache.UtilCacheHelper.set<string>(key, "true", 1);
        //    redis.Set(key, "true", 1);
        //}


        ///// <summary>
        ///// 不能用作分布式redis，不准确，在已有分布式redis下协助使用
        ///// </summary>
        ///// <param name="key">锁的Key</param>
        ///// <param name="lockExpirySec">锁的时长（单位：秒）</param>
        ///// <returns>true：加锁成功、false：加锁失败</returns>
        //public static bool getLock(string key, int lockExpirySec = 60)
        //{
        //    string lockobj = redis.Get<string>(key);
        //    if (lockobj != null)
        //    {
        //        return false;
        //    }
        //    redis.Set(key, "true", new TimeSpan(0, 0, 0, lockExpirySec));
        //    return true;
        //}
        //public static void delLock(string key)
        //{
        //    redis.Remove(key);
        //}


        public static long DeleteHash<T>(string redisKey, string[] hashFields)
        {
            return redis.HashDel<T>(redisKey, hashFields);
        }
        public static void SetHash<T>(string redisKey, string hashField, T value)
        {
            redis.HashAdd(redisKey, hashField, value);
        }
        public static T HashGetOne<T>(string redisKey, string hashField)
        {
            return redis.HashGetOne<T>(redisKey, hashField);
        }
        public static List<T> GetHash<T>(string redisKey, string[] hashFields)
        {
            return redis.HashGet<T>(redisKey, hashFields);
        }
        public static IDictionary<string, T> HashGetAll<T>(string redisKey)
        {
            return redis.HashGetAll<T>(redisKey);
        }
        public static void ListAdd<T>(string redisKey, T value)
        {
            redis.ListAdd(redisKey, value);
        }
        public static List<T> ListGetAll<T>(string redisKey)
        {
            try
            {
                return redis.ListGetAll<T>(redisKey);
            }
            catch(Exception e)
            {
                return null;
            }
        }
        public static T ListGet<T>(string redisKey, T value)
        {
            return redis.ListGet(redisKey, value);
        }
        public static bool ListRemove<T>(string redisKey, T value)
        {
            return redis.ListRemove(redisKey, value);
        }
        public static void ListClear<T>(string redisKey)
        {
            redis.ListClear<T>(redisKey);
        }
        ///// <summary>
        ///// 存储一个对象（该对象会被序列化保存）
        ///// </summary>
        ///// <param name="redisKey">名称</param>
        ///// <param name="redisValue">值</param>
        ///// <param name="expiry">时间</param>
        ///// <returns></returns>
        //public static bool StringSet<T>(string redisKey, T redisValue, int min = 30)
        //{
           

        //    //return UtilRedisNewLife.set<T>(redisKey, redisValue, min);
        //    TimeSpan expiry = new TimeSpan(0, min, 0);
        //    var json = JsonConvert.SerializeObject(redisValue);// Serialize(redisValue);

        //    UtilMemoryCacheHelper.set<string>(redisKey, json, min * 60);
        //    return true;
        //    //return UtilRedisNewLife.set(redisKey, json, min);
        //    // return _DB.StringSet(redisKey, json, expiry);
        //}

        ///// <summary>
        ///// 获取一个对象（会进行反序列化）
        ///// </summary>
        ///// <param name="redisKey">名称</param>
        ///// <param name="expiry">时间</param>
        ///// <returns></returns>
        //public static T StringGet<T>(string redisKey, TimeSpan? expiry = null)
        //{
        //    string result = UtilMemoryCacheHelper.get<string>(redisKey);
        //  //  string result = UtilRedisNewLife.get<string>(redisKey);
        //    if (!string.IsNullOrEmpty(result))
        //    {
        //        return JsonConvert.DeserializeObject<T>(result);
        //    }
        //    return default(T);

        //}
    }

}
